package com.example.huajia.wx.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.example.huajia.wx.common.util.SnowflakeIdWorker;
import com.example.huajia.wx.db.dao.TbUserDao;
import com.example.huajia.wx.db.pojo.MessageEntity;
import com.example.huajia.wx.db.pojo.TbUser;
import com.example.huajia.wx.exception.HJException;
import com.example.huajia.wx.service.UserService;
import com.example.huajia.wx.task.ActiveCodeTask;
import com.example.huajia.wx.task.MessageTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.example.huajia.wx.common.util.RedisKey.USER_INFO_KEY;

@Service
@Slf4j
@Scope("prototype")
public class UserServiceImpl implements UserService {
    @Value("${wx.app-id}")
    private String appId;
    @Value("${wx.app-secret}")
    private String appSecret;
    @Resource
    private TbUserDao userDao;
    @Resource
    private ActiveCodeTask activeCodeTask;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private MessageTask messageTask;


    private String getOpenId(String code) {
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        HashMap map = new HashMap();
        map.put("appid", appId);
        map.put("secret", appSecret);
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");
        String response = HttpUtil.post(url, map);
        JSONObject json = JSONUtil.parseObj(response);
        String openId = json.getStr("openid");
        if (openId == null || openId.length() == 0) {
            throw new RuntimeException("临时登录系统凭证错误");
        }
        return openId;
    }

    @Override
    public int registerUser(String code, String nickname, String photo) {
        String openId = getOpenId(code);
        SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker();
        int userId = snowflakeIdWorker.nextId();
        HashMap param = new HashMap();
        param.put("id", userId);
        param.put("openId", openId);
        param.put("nickname", nickname);
        param.put("photo", photo);
        param.put("role", "[0]");
        param.put("status", 1);
        param.put("createTime", new Date());
        param.put("root", false);
        Integer id = userDao.searchIdByOpenId(openId);
        if (id != null){
            throw new HJException("账户已存在，无需重复注册!");
        }
        userDao.insert(param);
        MessageEntity entity = new MessageEntity();
        entity.setSenderId(0);
        entity.setSenderName("系统消息");
        entity.setUuid(IdUtil.simpleUUID());
        entity.setMsg("恭喜您注册成功，请及时更新你的个人信息。");
        entity.setSendTime(new Date());
        messageTask.sendAsync(id + "", entity);
        return userId;
    }



    @Override
    public Integer login(String code) {
        String openId = getOpenId(code);
        Integer id = userDao.searchIdByOpenId(openId);
        if (id == null) {
            throw new HJException("账户不存在，请前往注册！");
        }
        //从消息队列中接收消息转移到消息表
        messageTask.receiveAsync(id+"");
        return id;
    }

    @Override
    public TbUser searchById(int userId) {
        TbUser user = userDao.searchById(userId);
        return user;
    }

    @Override
    public ArrayList<HashMap> searchUserById(int userId) {
        //在数据库查询出来后要把查到的数据放到redis里面
        ArrayList<HashMap> list = userDao.searchUserById(userId);
        String key = USER_INFO_KEY + userId;
        //查询完之后需要把数据写到redis里面去
        for (HashMap map : list){
            redisTemplate.opsForList().rightPush(key, map);
        }
        redisTemplate.expire(key, 300L, TimeUnit.MINUTES);
        //返回数据
        return list;
    }


    @Override
    public HashMap searchUserSummary(int userId) {
        HashMap map = userDao.searchUserSummary(userId);
        return map;
    }



    @Override
    public ArrayList<HashMap> searchMembers(List param) {
        ArrayList<HashMap> list = userDao.searchMembers(param);
        return list;
    }

    @Override
    public List<HashMap> selectUserPhotoAndName(List param) {
        List<HashMap> list = userDao.selectUserPhotoAndName(param);
        return list;
    }

    @Override
    public void insertUser(HashMap param) {
        int row = userDao.insert(param);
        if (row == 1) {
            String email = (String) param.get("email");
            //根据email查找新添加用户的主键值
            int userId = userDao.searchUserIdByEmail(email);
            //生成激活码，并且用邮件发送
            activeCodeTask.sendActiveCodeAsync(userId, email);
        } else {
            throw new HJException("员工数据添加失败");
        }
    }


    @Override
    public int updateUserInfo(HashMap param) {
        //更新员工记录
        int rows = userDao.updateUserInfo(param);
        //更新成功就发送消息通知
        if (rows == 1) {
            Integer userId = (Integer) param.get("userId");
            //然后将redis里的数据失效
            String key = USER_INFO_KEY + userId;
            redisTemplate.expire(key, 1L, TimeUnit.SECONDS);
            String msg = "你的个人资料已经被成功修改";
            MessageEntity entity = new MessageEntity();
            entity.setSenderId(0);  //系统自动发出
            entity.setSenderPhoto("../../static/system.jpg");
            entity.setSenderName("系统消息");
            entity.setMsg(msg);
            entity.setSendTime(new Date());
            messageTask.sendAsync(userId.toString(), entity);
        }
        return rows;
    }


    @Override
    public JSONObject searchUserContactList() {
        ArrayList<HashMap> list = userDao.searchUserContactList();
        String letter = null;
        JSONObject json = new JSONObject(true);
        JSONArray array = null;
        for (HashMap<String, String> map : list) {
            String name = map.get("name");
            String firstLetter = PinyinUtil.getPinyin(name).charAt(0) + "";
            firstLetter = firstLetter.toUpperCase();
            if (letter == null || !letter.equals(firstLetter)) {
                letter = firstLetter;
                array = new JSONArray();
                json.set(letter, array);
            }
            array.put(map);
        }
        return json;
    }

    @Override
    public int searchUserPoint(Integer id) {
        int row = userDao.searchUserPoint(id);
        return row;
    }

    @Override
    public int updateUserPoint(HashMap param) {
        int row = userDao.updateUserPoint(param);
        return row;
    }

    @Override
    public ArrayList<HashMap> getAcceptId(String friend) {
        ArrayList<HashMap> acceptId = userDao.getAcceptId(friend);
        return acceptId;
    }

}
